package aop;

import annotation.AfterReturning;
import annotation.Before;

import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.sql.Blob;
import java.util.HashSet;
import java.util.Set;

/**
 * @author Zee
 * @version 1.0
 * @date 2021/10/13
 */
public class AopProxy implements InvocationHandler {
    AdvisedSupport advisedSupport;

    public AopProxy(AdvisedSupport advisedSupport) {
        this.advisedSupport = advisedSupport;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        Method m = proxy.getClass().getMethod(method.getName());
        Set<String> annotationType = new HashSet<>();
        Annotation[] annotations = m.getAnnotations();
        for (Annotation annotation : annotations) {
            annotationType.add("@" + annotation.annotationType().getTypeName());
        }

        if (annotationType.contains(advisedSupport.getPointCut()) && advisedSupport.getMethod().isAnnotationPresent(Before.class)) {
            advisedSupport.getMethod().invoke(advisedSupport.getAspect(), new JoinPoint(advisedSupport.getTarget(), method, args));
        }
        Object obj = method.invoke(advisedSupport.getTarget(), args);
        if (annotationType.contains(advisedSupport.getPointCut()) && advisedSupport.getMethod().isAnnotationPresent(AfterReturning.class)) {
            advisedSupport.getMethod().invoke(advisedSupport.getAspect(), new JoinPoint(advisedSupport.getTarget(), method, args));
        }
        return obj;
    }


}
